package com.hedl.practice.diyJava.gather.lists;

import java.util.*;

public class Study_List {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("apple");
        list.add("pear");
        list.add("apple");
        list.add(null);     //可以添加null

        System.out.println(list.size());    //允许重复添加元素，size=3
        System.out.println(list.get(0).equals(list.get(2)));        //true
        System.out.println(list.get(3));

        System.out.println("===================");
        //创建list
        //jdk版本限制，List<String> ls = List.of()//返回包含零元素的不可修改列表of中可以写入数组，直接创建list数组；

        //List和Array转换：
        //第一种是调用toArray()方法直接返回一个Object[]数组：
        //这种方法会丢失类型信息，所以实际应用很少；
        Object[] array = list.toArray();
        for (Object o : array) {
            System.out.println("List和Array转换，使用toArray，方法一："+o);
        }

        System.out.println("============================================");
        /**
         * 第二种方式是给toArray(T[])传入一个类型相同的Array，List内部自动把元素复制到传入的Array中
         */
        String[] array_1 = list.toArray(new String[list.size()]);     //这里string数组中可以改写成动态的获取：list.size()
        for (String s : array_1) {
            System.out.println("List和Array转换，使用toArray(T[])，方法二："+s);
        }

        System.out.println("============================================");
        /**
         * 最后一种更简洁的写法是通过List接口定义的T[] toArray(IntFunction<T[]> generator)方法：
         * 报错，不可写
         */
        /*List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        list1.add(4);

        Integer[] array_2 = list1.toArray(Integer[]::new);*/

        System.out.println("============================================");
        /**
         * 把Array变为List就简单多了，通过List.of(T...)方法最简单：因为这里我们jdk版本过低无法使用of()方法；
         *
         * jdk11一下使用：Arrays.asList();把Array变为List
         *
         */

        String[] array_2 = {"你好","世界","张三","李四"};
        List<String> list1 = Arrays.asList(array_2);
        for (String s : list1) {
            System.out.println(">>>>>>"+s);
        }

        /**
         * 因为我们jdk版本过低，可以使用Arrays.asList()替代List.of();
         */
        System.out.println("数组》》》》"+Arrays.toString(array_2));
        List<String> list2 = Arrays.asList("Zhang San","Li Si","Xiao Ming");
        for (String s : list2) {
            System.out.println("集合》》》》"+s);
        }

        System.out.println("===================练习====================");
        //练习,给定一组连续的整数，例如：10，11，12，……，20，但其中缺失一个数字，试找出缺失的数字：
        final int start = 10;
        final int end = 20;
        List<Integer> list3 = new ArrayList<>();
        for (int i = start; i <= end; i++){
            list3.add(i);
        }

        //随机删除list中的一个元素
        int removed = list3.remove((int) (Math.random() * list3.size()));
        int found = findMissIngNumber(start,end,list3);
        System.out.println(list3.toString());
        System.out.println("missing number:"+found);
        System.out.println(removed == found ? "测试成功！" : "测试失败！");

        System.out.println("=========================增强版练习=======================");

        //增强版：和上述题目一样，但整数不再有序，试找出缺失的数字：
        //洗牌算法shuffle可以随机交换List中的元素位置:
        Collections.shuffle(list3);
        // 随机删除List中的一个元素:
        int removed1 = list3.remove((int) (Math.random() * list.size()));
        System.out.println(removed1);
        int found1 = findMissIngNumber1(start,end,list3);
        System.out.println(list3.toString());
        System.out.println("missing number:"+found1);
        System.out.println(removed1 == found1 ? "测试成功！" : "测试失败！");

    }

    private static int findMissIngNumber1(int start, int end, List<Integer> list3) {
        for (int i = start; i <= end; i++) {
            if (!list3.contains(i)) {
                return i;
            }
        }
        return 0;
    }

    private static int findMissIngNumber(int start, int end, List<Integer> list3) {
        for (int i = 0; i < list3.size();i++){
            if (list3.get(i) == start){
                start++;
            }
        }
        return start;
    }
}
